﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.EventSystems;

public abstract class GameData
{
    public abstract GameUser GameUser { get; set; }
    
    public GameData()
    {
        this.GameUser = new GameUser();
    }
}

public class Dodge
{
    const string loginNewKey = "DodgeLoginNewKey";
    public static bool loginNew
    {
        get => PlayerPrefs.GetInt(loginNewKey) > 0;
        set => PlayerPrefs.SetInt(loginNewKey,value?1:0);
    } 
    
}

public abstract class Game : MonoBehaviour {

      protected static Game _instance;
      public static Game Instance
      {
          get
          {
              return _instance;
          }
      }
    
    /// <summary>
    /// 游戏设置（音乐音效等）
    /// </summary>
    GameSetting m_GameSettting;
    public GameSetting gameSetting { get { return m_GameSettting; } }


    /// <summary>
    /// 用户数据
    /// </summary>
    public GameUser user
    {
        get
        {
            return data?.GameUser;
        }
    }

    /// <summary>
    /// 保存在内存的全局数据
    /// </summary>
    protected virtual GameData data { get; set; }
    
    /// <summary>
    /// 登录
    /// </summary>
    private ILoginCtrl m_LoginCtrl;
    public ILoginCtrl loginCtrl => m_LoginCtrl;
    
    /// <summary>
    /// 数据埋点
    /// </summary>
    private IDataTracking m_DataTracking;
    public IDataTracking dataTracking => m_DataTracking;
    
    GameObject m_ModelSceneParent;
    public GameObject modelSceneParent
    {
        get
        {
            if (m_ModelSceneParent == null)
                m_ModelSceneParent = new GameObject("ModelSceneParent");

            return m_ModelSceneParent;
        }
    }
    /// <summary>
    /// 广告
    /// </summary>
    protected AdManager m_AdManager;
    public AdManager adManager => m_AdManager;

    public abstract BattleDataConfig battleDataConfig { get; }


    public const string GuideStepKey = "GuideStep";
    public int curGuideStep
    {
        get { return PlayerPrefs.GetInt(GuideStepKey); }
        set { PlayerPrefs.SetInt(GuideStepKey, value); }
    }

    protected virtual void PreInit ()
    {
        m_GameSettting = new GameSetting();
        m_GameSettting.Load();
        m_GameSettting.AddAudioSettingListener(AudioController.instance);
    }

    protected virtual LocalUserData GetLocalUserData()
    {
#if Test
        LocalUserData localUserData = new LocalUserData();
        localUserData.InitTestData();
        return localUserData
#endif
        return null;
    }
    
    public const string LocalUserDataKey = "LocalUserData";


    //public Reporter reporter;

    void Awake()
    {
        _instance = this;
        DontDestroyOnLoad(gameObject);
        this.PreInit();
        
        Screen.sleepTimeout = SleepTimeout.NeverSleep;

        _Awake();
        
        GameStart();
    }

    protected virtual void _Awake()
    {
        
    }

    protected virtual void Start()
    {
       
    }

    void GameStart()
    {
        Application.targetFrameRate = 60;

        //初始化用户数据
        this.user.Init(GetLocalUserData());

        //关闭多点触控
        //Input.multiTouchEnabled = false;

        //添加事件组件
        var eventSystem = FindObjectOfType<EventSystem>();
        if (eventSystem == null)
        {
            var es = new GameObject("EventSystem");
            es.AddComponent<EventSystem>();
            es.AddComponent<StandaloneInputModule>();
            es.transform.SetParent(transform);
        }
        //var AudioListener = FindObjectOfType<AudioListener>();
        //if (AudioListener == null)
        //    gameObject.AddComponent<AudioListener>();
    }
    

    #region game level
    
    private static int minLevel = 1;
    public int curLevel => this.user.level;
    
    public void LoadCurLevelGame()
    {
        if(s_CurLevel == -1)
            s_CurLevel = user.level;

        GameDebug.LogError($"s_level:{s_CurLevel}"); 
        LoadGame(s_CurLevel);
    }
    
    /// <summary>
    /// 统计用的等级，达到最大关卡后会继续增加
    /// </summary>
    public static int s_CurLevel
    {
        get { return PlayerPrefs.GetInt("CurLevel", -1); }
        set
        {
            PlayerPrefs.SetInt("CurLevel", value);
        }
    }
    public void NextLevel()
    {
        if(s_CurLevel == -1)
            s_CurLevel = user.level;

        s_CurLevel++;

        
        if (user.level < s_CurLevel)
        {
            user.UpdateLevel(s_CurLevel);
        }
    }

    public void LoadNextLevelGame(bool withFs = false)
    {
        NextLevel();
        LoadCurLevelGame();
    }
    
    public int curMapId { get; set; }

    public int curLoadLevel { get; set; }
    /// <summary>
    /// 加载关卡场景
    /// </summary>
    /// <param name="level"></param>
    /// <param name="useDefaultLoadingAnim"></param>
    /// <returns></returns>
    public void LoadGame(int level,int mapId = 0)
    {
        if (level < minLevel)
            level = minLevel;

        GameDebug.Log($"mapId:{level}");
        curLoadLevel = level;
        BattleData battleData = GetBattleData(level, mapId);

        curMapId = battleData.mapId;
        LoadingSceneController.LoadScene($"Level{battleData.mapId}");
    }

    protected virtual BattleData GetBattleData(int level,int mapId)
    {
        BattleData battleData = new BattleData();
        battleData.level = level;
        if (mapId > 0)
            battleData.mapId = mapId;
        else
            battleData.mapId = MapId2LoopMapId(level,battleDataConfig.loopMaxLevel);
        //GameDebug.LogShowy($"mapEdit count:{battleData.mapData?.mapEditWidgets?.Count} ");

        battleData.players = new List<BattlePlayerData>();
        battleData.players.Add(new BattlePlayerData()
        {
            playerId = user.id,
            name = user.name,
        });
        return battleData;
    }
    
    public static int MapId2LoopMapId(int mapId,int loopMaxLevel)
    {
        int toLoadMapId = mapId;
        
        if (mapId > 0 && mapId % loopMaxLevel == 0)
            toLoadMapId = loopMaxLevel;
        else
            toLoadMapId %= loopMaxLevel;
        
        GameDebug.Log($"mapId:{mapId} -> {toLoadMapId}   loopMaxLevel:{loopMaxLevel}");
        return toLoadMapId;
    }
    
    #endregion
    
    
    #region notice
     /// <summary>
    /// 通知面板
    /// </summary>
    NoticePanel m_NoticePanel;
    public NoticePanel noticePanel
    {
        get
        {
            if (m_NoticePanel == null)
            {
                var pref = ResourceManager.Load<NoticePanel>(ViewPath.NoticePanel);
                m_NoticePanel = Instantiate(pref, transform);
                
                GameDebug.LogError("New Notice Panel");
            }
            return m_NoticePanel;
        }
    }

    public NoticePanel ShowNoticePanel(string content)
    {
        GameDebug.LogShowy("content：" + content);
        noticePanel.Init(new NoticePanelData("消息", content, "OK"/*new MultiLangKey("confirm")*/, "", null, null));//提示

        //noticePanel.Init(new NoticePanelData(Localization.instance.GetValue("prompt"), content, "OK"/*new MultiLangKey("confirm")*/, "", null, null));//提示

        return noticePanel;
    }
    public NoticePanel ShowNoticePanel(string content, Action onConfirm )
    {
        GameDebug.LogShowy("content：" + content);

        noticePanel.Init(new NoticePanelData(Localization.instance.GetValue("prompt"), content, "OK"/*new MultiLangKey("confirm")*/, "" , onConfirm, null));//提示

        return noticePanel;
    }
    public NoticePanel ShowNoticePanelWithTwoBtn(string content, Action onConfirm ,Action onCancel)
    {
        return ShowNoticePanelWithTwoBtn(content,onConfirm,onCancel,"OK",Localization.instance.GetValue("cancel"));
    }

    public NoticePanel ShowNoticePanelWithTwoBtn(string content, Action onConfirm, Action onCancel, string ok, string cancel)
    {
        GameDebug.LogShowy("content：" + content);      

        noticePanel.Init(new NoticePanelData(Localization.instance.GetValue("prompt"), content, ok, cancel, onConfirm, onCancel));//提示//取消

        return noticePanel;
    }
    public void ShowMsg(string msg)
    {  
        GameDebug.LogShowy("msg:"+msg);      

        noticePanel.Init(new NoticePanelData(msg, true));
    }
    public void HideMsg()
    {
        if(this.m_NoticePanel)
            this.m_NoticePanel.HideMsg();
    }

    #endregion
    
    
    
}

